home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / VIVIDUS / QD3D.SIT / qd3d / qd3dLib.c < prev   
C/C++ Source or Header  |  1991-10-05  |  18KB  |  862 lines

  1. #include    <Cqd3dPort.h>
  2. #include    <gouraud.h>
  3. #include    <SANE.h>
  4.  
  5. extern    Cqd3dPort    *the3dPort;
  6.  
  7. /*    ======================================================================
  8.  
  9.     Cqd3dPort primitive three dimensional drawing routine library.
  10.     
  11.     This is part of the qd3d Vividus Source Code Library.  See the
  12.     extern qd3d.doc documentation file for usage.  See individual
  13.     routines for routine documentation.
  14.     
  15.     Copyright 1991 by Vividus Consulting.
  16.     
  17.     This is not public domain source code.  You may not copy and
  18.     paste from this source code.  Read your Vividus Licensing
  19.     agreement for details and other restrictions.
  20.  
  21.     ======================================================================    */
  22.  
  23. static    FixedVector    fdc[PolyMaxN];
  24. static    FixedVector    cfdc[PolyMaxN];
  25. static    vector        eyec[PolyMaxN];
  26. static    vector        ceyec[PolyMaxN];
  27. static    vector        ndc[PolyMaxN];
  28. static    vector        cndc[PolyMaxN];
  29. static    vector        tcolor[PolyMaxN];
  30. static    vector        ccolor[PolyMaxN];
  31. static    FixedVector    frgb[PolyMaxN];
  32. static    FixedVector    cfrgb[PolyMaxN];
  33.  
  34. /*    ============================================================    */
  35. /*    Color primitives:                                                */
  36.  
  37. void
  38. Color2RGB(vector *c, RGBColor *rgb)
  39. /*
  40.     This converts the color vector c to the equivalent RGBColor in rgb.
  41. */
  42. {
  43.     FixedVector    tc;
  44.     
  45.     GetFColor(c, &tc);
  46.     cv2rgb(&tc, rgb);
  47. }
  48.  
  49. void
  50. RGB2Color(RGBColor *rgb, vector *c)
  51. /*
  52.     This converts the RGBColor in rgb to the equivalent color vector c.
  53. */
  54. {
  55.     FixedVector    tc;
  56.     
  57.     c->x = rgb->red/65535.0;
  58.     c->y = rgb->green/65535.0;
  59.     c->z = rgb->blue/65535.0;
  60. }
  61.  
  62. void
  63. vForeColor(vector *c)
  64. /*
  65.     Set the foreground color to that indicated by c.
  66. */
  67. {
  68.     RGBColor    rgb;
  69.     
  70.     Color2RGB(c, &rgb);
  71.     RGBForeColor(&rgb);
  72. }
  73.  
  74. void
  75. GetFColor(vector *c, FixedVector *fc)
  76. /*
  77.     Given the color c, this returns the equivalent fixed point
  78.     representation in fc.
  79.  
  80.     Warning:    This is a private function to the qd3d library and is
  81.                 highly subject to change or removal.
  82. */
  83. {
  84. #if    0
  85.     if ((c->x > 1.0) || (c->y > 1.0) || (c->z > 1.0))
  86.         Debugger();
  87.     if ((c->x < 0.0) || (c->y < 0.0) || (c->z < 0.0))
  88.         Debugger();
  89. #endif
  90.  
  91.     fc->x = ((long)(65535.0 * c->x)) << 15;
  92.     fc->y = ((long)(65535.0 * c->y)) << 15;
  93.     fc->z = ((long)(65535.0 * c->z)) << 15;
  94. }
  95.  
  96. void
  97. cv2rgb(FixedVector *f, RGBColor *rgb)
  98. /*
  99.     Given the fixed point color in f, this returns the appropriate
  100.     RGBColor in rgb.
  101.  
  102.     Warning:    This is a private function to the qd3d library and is
  103.                 highly subject to change or removal.
  104. */
  105. {
  106.     rgb->red = HiWord(f->x << 1);
  107.     rgb->green = HiWord(f->y << 1);
  108.     rgb->blue = HiWord(f->z << 1);
  109. }
  110.  
  111. void
  112. rgb2cv(RGBColor *rgb, FixedVector *f)
  113. /*
  114.     Given the RGBColor rgb, this returns the equivalent fixed point
  115.     representation in f.
  116.  
  117.     Warning:    This is a private function to the qd3d library and is
  118.                 highly subject to change or removal.
  119. */
  120. {
  121.     f->x = (long)(rgb->red) << 15;
  122.     f->y = (long)(rgb->green) << 15;
  123.     f->z = (long)(rgb->blue) << 15;
  124. }
  125.  
  126. static    void
  127. LoadFColors(int    n, vector color[]) {
  128. /*
  129.     Note: that cfdc must be set up BEFORE calling this routine.
  130.  
  131.     Warning:    This is a private function to the qd3d library and is
  132.                 highly subject to change or removal.
  133. */
  134.     int    i;
  135.     
  136.     for (i = 0; i < n; i++) {
  137.         GetFColor(&color[i], &cfrgb[i]);
  138.         if (the3dPort->usedepthque) {
  139.             DepthColor(&cfrgb[i], cfdc[i].z, &cfrgb[i]);
  140.         }
  141.     }
  142.     return;
  143.     
  144.     /*    The following notice may not be removed under any
  145.         circumstance.  See your licensing agreement.        */
  146.     asm {
  147.         dc.b    "qd3dLib Copyright 1991 Vividus Consulting"
  148.     }
  149. }
  150.  
  151. /*    ------------------------------------------------------------    */
  152. /*    The following should be considered private to the qd3d library.    */
  153.  
  154. static struct    {
  155.     int        size;
  156.     Rect    bbox;
  157.     Point    points[PolyMaxN];
  158. }    mypoly;
  159.  
  160. static PolyPtr    polyptr = (PolyPtr)&mypoly;
  161.  
  162. /*
  163.     The following defines have obvious and intended side affects.  Ie.
  164.     They aren't just functions.
  165. */
  166. #define    MAXA(a,b) {if ( b > a) a = b;}
  167. #define    MINA(a,b) {if ( b < a) a = b;}
  168.  
  169. static PolyForm(int n, FixedVector fx[])
  170. /*
  171.     This routine sets mypoly to reflect the polygon defined by n and fx.
  172.     
  173.     This is a quicker way of making a quickdraw polygon than OpenPoly.
  174. */
  175. {
  176.     int            i = 0;
  177.     IntVector    p;
  178.     
  179.     mypoly.size = 10 + (n + 1) * sizeof(Point);
  180.     fv2iv(&fx[i], &p);
  181.     mypoly.bbox.top = p.y;
  182.     mypoly.bbox.left = p.x;
  183.     mypoly.bbox.right = p.x;
  184.     mypoly.bbox.bottom = p.y;
  185.     for (i = 0; i < n; i++) {
  186.         fv2iv(&fx[i], &p);
  187.         mypoly.points[i].h = p.x;
  188.         mypoly.points[i].v = p.y;
  189.         MINA(mypoly.bbox.top, p.y);
  190.         MINA(mypoly.bbox.left, p.x);
  191.         MAXA(mypoly.bbox.right, p.x);
  192.         MAXA(mypoly.bbox.bottom, p.y);
  193.     }
  194.     mypoly.points[n].h = mypoly.points[0].h;
  195.     mypoly.points[n].v = mypoly.points[0].v;
  196. }
  197.  
  198. /*    ============================================================    */
  199. /*    Drawing primitives:                                                */
  200.  
  201. int
  202. Qd3dError(void)
  203. /*
  204.     This returns the most recently occured qd3d error of the current
  205.     3d port.
  206.     
  207.     Note:    this routine is what clears the last reported error
  208.             instead of the individual routines!
  209. */
  210. {
  211.     return(the3dPort->Qd3dError());
  212. }
  213.  
  214. void
  215. MoveTo3d(vector *x)
  216. /*
  217.     Move to the position x without drawing.
  218.     
  219.     This routine will also reposition the 2d pen -- useful for
  220.     positioning text.  With this application, be sure and check
  221.     Qd3dError to see if the pen has been positioned outside
  222.     the current view volume.
  223. */
  224. {
  225.     FixedVector    p;
  226.     int            n = 1;
  227.     
  228.     vcopy(x, &the3dPort->position);
  229.     TranClipProjf(&n, &the3dPort->position, &p);
  230.     MoveTo(HiWord(p.x), HiWord(p.y));
  231.     
  232.     if (n == 0)
  233.         the3dPort->lastError = moveOutVV;
  234. }
  235.  
  236. void
  237. LineTo3d(vector *x)
  238. /*
  239.     Move to and draw a line from the present position to the position
  240.     x.
  241. */
  242. {
  243.     vector    ls[2];
  244.     
  245.     vcopy(&the3dPort->position, &ls[0]);
  246.     vcopy(x, &ls[1]);
  247.     Poly3dLine(2, ls);
  248.     
  249.     MoveTo3d(x);
  250. }
  251.  
  252. void
  253. Poly3dLine(int n, vector x[])
  254. /*
  255.     Draw n-1 line segments through the ordered list of points x.
  256. */
  257. {
  258.     IntVector    p;
  259.     int            i = 0;
  260.     RGBColor    saveColor, rgb;
  261.  
  262.     GetForeColor(&saveColor);
  263.     
  264.     Transform(n, x, eyec);
  265.     
  266.     for (i = 0; i < n-1; i++) {
  267.         if (!Line3dClip(&eyec[i], &eyec[i+1], &ceyec[0], &ceyec[1]))
  268.             continue;
  269.         Projectf(2, ceyec, cfdc);
  270.         
  271.         if (the3dPort->usedepthque) {
  272.             rgb2cv(&saveColor, &frgb[0]);
  273.             DepthColor(&frgb[0], cfdc[0].z, &cfrgb[0]);
  274.             DepthColor(&frgb[0], cfdc[1].z, &cfrgb[1]);
  275.             if (the3dPort->onlyqd) {
  276.                 fvscale(0x08000L, &cfrgb[0], &cfrgb[0]);
  277.                 fvscale(0x08000L, &cfrgb[1], &cfrgb[1]);
  278.                 fvadd(&cfrgb[0], &cfrgb[1], &cfrgb[0]);
  279.                 cv2rgb(&cfrgb[0], &rgb);
  280.                 RGBForeColor(&rgb);
  281.             }
  282.         } else {
  283.             if (!the3dPort->onlyqd) {
  284.                 rgb2cv(&saveColor, &cfrgb[0]);
  285.                 rgb2cv(&saveColor, &cfrgb[1]);
  286.             }
  287.         }
  288.         
  289.         if (the3dPort->onlyqd) {
  290.             fv2iv(&cfdc[0], &p);
  291.             MoveTo(p.x, p.y);
  292.             fv2iv(&cfdc[1], &p);
  293.             LineTo(p.x, p.y);
  294.         } else {
  295.             C3dLine(&cfdc[0], &cfdc[1], &cfrgb[0], &cfrgb[1]);
  296.         }
  297.     }
  298.  
  299.     RGBForeColor(&saveColor);
  300. }
  301.  
  302. void
  303. PolyC3dLine(int n, vector x[], vector c[])
  304. /*
  305.     Draw n-1 line segments through the ordered list of points x.  Each
  306.     line segment will be color blended between the associated colors
  307.     in c.
  308. */
  309. {
  310.     IntVector    p;
  311.     int            i = 0;
  312.     RGBColor    saveColor, rgb;
  313.  
  314.     GetForeColor(&saveColor);
  315.     
  316.     Transform(n, x, eyec);
  317.     
  318.     for (i = 0; i < n-1; i++) {
  319.         if (!LineC3dClip(&eyec[i], &eyec[i+1], &ceyec[0], &ceyec[1],
  320.                 &c[i], &c[i+1], &ccolor[i], &ccolor[i+1]))
  321.             continue;
  322.         Projectf(2, ceyec, cfdc);
  323.         
  324.         if (the3dPort->usedepthque) {
  325.             GetFColor(&ccolor[i], &frgb[0]);
  326.             GetFColor(&ccolor[i+1], &frgb[1]);
  327.             DepthColor(&frgb[0], cfdc[0].z, &cfrgb[0]);
  328.             DepthColor(&frgb[0], cfdc[1].z, &cfrgb[1]);
  329.             if (the3dPort->onlyqd) {
  330.                 fvscale(0x08000L, &cfrgb[0], &cfrgb[0]);
  331.                 fvscale(0x08000L, &cfrgb[1], &cfrgb[1]);
  332.                 fvadd(&cfrgb[0], &cfrgb[1], &cfrgb[0]);
  333.                 cv2rgb(&cfrgb[0], &rgb);
  334.                 RGBForeColor(&rgb);
  335.             }
  336.         } else {
  337.             if (!the3dPort->onlyqd) {
  338.                 rgb2cv(&saveColor, &cfrgb[0]);
  339.                 rgb2cv(&saveColor, &cfrgb[1]);
  340.             }
  341.         }
  342.         
  343.         if (the3dPort->onlyqd) {
  344.             fv2iv(&cfdc[0], &p);
  345.             MoveTo(p.x, p.y);
  346.             fv2iv(&cfdc[1], &p);
  347.             LineTo(p.x, p.y);
  348.         } else {
  349.             C3dLine(&cfdc[0], &cfdc[1], &cfrgb[0], &cfrgb[1]);
  350.         }
  351.     }
  352.     RGBForeColor(&saveColor);
  353. }
  354.  
  355. void
  356. Poly3dMark(int n, vector x[], void (*markf)(vector *pos))
  357. /*
  358.     Mark the n points in x using the marking function markf.
  359. */
  360. {
  361.     int        i;
  362.  
  363.     for (i = 0; i < n; i++) {
  364.         (*markf)(&x[i]);
  365.     }
  366. }
  367.  
  368. void
  369. PolyC3dMark(int n, vector x[], void (*markf)(vector *pos), vector c[])
  370. /*
  371.     Mark the n points in x using the marking function markf with
  372.     the colors indentified in c.
  373. */
  374. {
  375.     int        i;
  376.     FixedVector    frgb;
  377.     vector    v;
  378.     RGBColor    saveColor, rgb;
  379.  
  380.     GetForeColor(&saveColor);
  381.  
  382.     for (i = 0; i < n; i++) {
  383.         GetFColor(&c[i], &frgb);
  384.         cv2rgb(&frgb, &rgb);
  385.         RGBForeColor(&rgb);
  386.         (*markf)(&x[i]);
  387.     }
  388.  
  389.     RGBForeColor(&saveColor);
  390. }
  391.  
  392. void
  393. Poly3dFrame(int n, vector x[])
  394. /*
  395.     Frame the polygon defined by the n vertices in x.
  396. */
  397. {
  398.     int        i;
  399.     double        ax, ay, bx, by;    
  400.     RGBColor    saveColor;
  401.     
  402.     if (n < 3)
  403.         return;
  404.  
  405.     Transform(n, x, eyec);
  406.     
  407.     Clip3d(&n, eyec, ceyec);
  408.     if (n < 3)
  409.         return;
  410.     Project(n, ceyec, cndc);
  411.     if (the3dPort->cullbacks) {
  412.         ax = cndc[1].x - cndc[0].x;
  413.         ay = cndc[1].y - cndc[0].y;
  414.         bx = cndc[2].x - cndc[1].x;
  415.         by = cndc[2].y - cndc[1].y;
  416.         if (ax * by - ay * bx > 0.0)
  417.             return;
  418.     }
  419.     ndc2fdc(n, cndc, cfdc);
  420.  
  421.     GetForeColor(&saveColor);
  422.     if (the3dPort->usedepthque) {
  423.         for (i = 0; i < n; i++) {
  424.             rgb2cv(&saveColor, &frgb[i]);
  425.             DepthColor(&frgb[i], cfdc[i].z, &cfrgb[i]);
  426.         }
  427.         if (the3dPort->onlyqd) {
  428.             FixedVector    t;
  429.             FixedVector    avgcolor = {0, 0, 0};
  430.             double    t2 = 1.0/n;
  431.             Fixed    s;
  432.             RGBColor    rgb;
  433.             extended    ext;
  434.             
  435. #if    __option(mc68881)
  436.             x96tox80(&t2, &ext);
  437.             s = X2Fix(ext);
  438. #else
  439.             x96tox80(&t2, &ext);
  440.             s = X2Fix(ext);
  441. #endif
  442.             for (i = 0; i < n; i++) {
  443.                 fvscale(s, &cfrgb[i], &t);
  444.                 fvadd(&t, &avgcolor, &avgcolor);
  445.             }
  446.             cv2rgb(&avgcolor, &rgb);
  447.             RGBForeColor(&rgb);
  448.         }
  449.     } else {
  450.         if (!the3dPort->onlyqd) {
  451.             for (i = 0; i < n; i++) {
  452.                 rgb2cv(&saveColor, &cfrgb[i]);
  453.             }
  454.         }
  455.     }
  456.  
  457.     if (the3dPort->onlyqd) {
  458.         PolyForm(n, cfdc);
  459.         FramePoly(&polyptr);
  460.     } else {
  461.         for (i = 0; i < n; i++) {
  462.             if (i == n-1)
  463.                 C3dLine(&cfdc[i], &cfdc[0], &cfrgb[i], &cfrgb[0]);
  464.             else
  465.                 C3dLine(&cfdc[i], &cfdc[i+1], &cfrgb[i], &cfrgb[i+1]);
  466.         }
  467.     }
  468.     RGBForeColor(&saveColor);
  469. }
  470.  
  471. void
  472. Poly3dFrameErase(int n, vector x[])
  473. /*
  474.     Erases the frame of the polygon defined by the n vertices in x.
  475.     
  476.     Note:  Presently this doesn't deal properly with the z-buffer.
  477. */
  478. {
  479.     int        i;
  480.     double        ax, ay, bx, by;    
  481.     RGBColor    saveColor, eraseColor;
  482.     
  483.     if (n < 3)
  484.         return;
  485.  
  486.     Transform(n, x, eyec);
  487.     
  488.     Clip3d(&n, eyec, ceyec);
  489.     if (n < 3)
  490.         return;
  491.     Project(n, ceyec, cndc);
  492.     if (the3dPort->cullbacks) {
  493.         ax = cndc[1].x - cndc[0].x;
  494.         ay = cndc[1].y - cndc[0].y;
  495.         bx = cndc[2].x - cndc[1].x;
  496.         by = cndc[2].y - cndc[1].y;
  497.         if (ax * by - ay * bx > 0.0)
  498.             return;
  499.     }
  500.     ndc2fdc(n, cndc, cfdc);
  501.  
  502.     GetForeColor(&saveColor);
  503.     GetBackColor(&eraseColor);
  504.     RGBForeColor(&eraseColor);
  505.  
  506.     if (the3dPort->onlyqd) {
  507.         PolyForm(n, cfdc);
  508.         FramePoly(&polyptr);
  509.     } else {
  510.         for (i = 0; i < n; i++) {
  511.             rgb2cv(&eraseColor, &cfrgb[0]);
  512.             if (i == n-1)
  513.                 C3dLine(&cfdc[i], &cfdc[0], &cfrgb[0], &cfrgb[0]);
  514.             else
  515.                 C3dLine(&cfdc[i], &cfdc[i+1], &cfrgb[0], &cfrgb[0]);
  516.         }
  517.     }
  518.     RGBForeColor(&saveColor);
  519. }
  520.  
  521. void
  522. PolyC3dFrame(int n, vector x[], vector c[])
  523. /*
  524.     Frame the polygon defined by the n vertices in x.  Color blend
  525.     the line segments according to the vertex colors in c.
  526. */
  527. {
  528.     int        i;
  529.     double        ax, ay, bx, by;    
  530.     RGBColor    saveColor;
  531.     
  532.     if (n < 3)
  533.         return;
  534.     Transform(n, x, eyec);
  535.     ClipC3d(&n, eyec, ceyec, c, ccolor);
  536.     if (n < 3)
  537.         return;
  538.     Project(n, ceyec, cndc);
  539.     if (the3dPort->cullbacks) {
  540.         ax = cndc[1].x - cndc[0].x;
  541.         ay = cndc[1].y - cndc[0].y;
  542.         bx = cndc[2].x - cndc[1].x;
  543.         by = cndc[2].y - cndc[1].y;
  544.         if (ax * by - ay * bx > 0.0)
  545.             return;
  546.     }
  547.     ndc2fdc(n, cndc, cfdc);
  548.     
  549.     GetForeColor(&saveColor);
  550.     LoadFColors(n, ccolor);
  551.     if (the3dPort->onlyqd) {
  552.         FixedVector    t;
  553.         FixedVector    avgcolor = {0, 0, 0};
  554.         double    t2 = 1.0/n;
  555.         Fixed    s;
  556.         RGBColor    rgb;
  557.         extended    ext;
  558.         
  559. #if    __option(mc68881)
  560.         x96tox80(&t2, &ext);
  561.         s = X2Fix(ext);
  562. #else
  563.         x96tox80(&t2, &ext);
  564.         s = X2Fix(ext);
  565. #endif
  566.         for (i = 0; i < n; i++) {
  567.             fvscale(s, &cfrgb[i], &t);
  568.             fvadd(&t, &avgcolor, &avgcolor);
  569.         }
  570.         cv2rgb(&avgcolor, &rgb);
  571.         RGBForeColor(&rgb);
  572.     }
  573.     
  574.     if (the3dPort->onlyqd) {
  575.         PolyForm(n, cfdc);
  576.         FramePoly(&polyptr);
  577.     } else {
  578.         for (i = 0; i < n; i++) {
  579.             if (i == n-1)
  580.                 C3dLine(&cfdc[i], &cfdc[0], &cfrgb[i], &cfrgb[0]);
  581.             else
  582.                 C3dLine(&cfdc[i], &cfdc[i+1], &cfrgb[i], &cfrgb[i+1]);
  583.         }
  584.     }
  585.     RGBForeColor(&saveColor);
  586. }
  587.  
  588. void
  589. Poly3dFill(int n, vector x[])
  590. /*
  591.     Fill the polygon defined by the n vertices in x.
  592. */
  593. {
  594.     int        i;
  595.     double        ax, ay, bx, by;    
  596.     RGBColor    saveColor;
  597.     
  598.     if (the3dPort->wireframe) {
  599.         Poly3dFrame(n, x);
  600.     } else {
  601.         if (n < 3)
  602.             return;
  603.         Transform(n, x, eyec);
  604.         Clip3d(&n, eyec, ceyec);
  605.         if (n < 3)
  606.             return;
  607.         Project(n, ceyec, cndc);
  608.         if (the3dPort->cullbacks) {
  609.             ax = cndc[1].x - cndc[0].x;
  610.             ay = cndc[1].y - cndc[0].y;
  611.             bx = cndc[2].x - cndc[1].x;
  612.             by = cndc[2].y - cndc[1].y;
  613.             if (ax * by - ay * bx > 0.0)
  614.                 return;
  615.         }
  616.         ndc2fdc(n, cndc, cfdc);
  617.         
  618.         GetForeColor(&saveColor);
  619.         if (the3dPort->usedepthque) {
  620.             for (i = 0; i < n; i++) {
  621.                 rgb2cv(&saveColor, &frgb[i]);
  622.                 DepthColor(&frgb[i], cfdc[i].z, &cfrgb[i]);
  623.             }
  624.             if (the3dPort->onlyqd) {
  625.                 FixedVector    t;
  626.                 FixedVector    avgcolor = {0, 0, 0};
  627.                 double    t2 = 1.0/n;
  628.                 Fixed    s;
  629.                 RGBColor    rgb;
  630.                 extended    ext;
  631.             
  632. #if    __option(mc68881)
  633.                 x96tox80(&t2, &ext);
  634.                 s = X2Fix(ext);
  635. #else
  636.                 x96tox80(&t2, &ext);
  637.                 s = X2Fix(ext);
  638. #endif
  639.                 for (i = 0; i < n; i++) {
  640.                     fvscale(s, &cfrgb[i], &t);
  641.                     fvadd(&t, &avgcolor, &avgcolor);
  642.                 }
  643.                 cv2rgb(&avgcolor, &rgb);
  644.                 RGBForeColor(&rgb);
  645.             }
  646.         } else {
  647.             if (!the3dPort->onlyqd) {
  648.                 for (i = 0; i < n; i++) {
  649.                     rgb2cv(&saveColor, &cfrgb[i]);
  650.                 }
  651.             }
  652.         }
  653.     
  654.         if (the3dPort->onlyqd) {
  655.             PolyForm(n, cfdc);
  656.             PaintPoly(&polyptr);
  657.         } else {
  658.             GouraudShade(n, cfdc, cfrgb);
  659.         }
  660.         RGBForeColor(&saveColor);
  661.     }
  662. }
  663.  
  664. void
  665. Poly3dErase(int n, vector x[])
  666. /*
  667.     Erase the polygon defined by the n vertices in x.
  668.     
  669.     Note:    Presently this doesn't appropriately deal with the z-buffer.
  670. */
  671. {
  672.     int        i;
  673.     double        ax, ay, bx, by;    
  674.     RGBColor    saveColor, eraseColor;
  675.     
  676.     if (the3dPort->wireframe) {
  677.         Poly3dFrameErase(n, x);
  678.     } else {
  679.         if (n < 3)
  680.             return;
  681.         Transform(n, x, eyec);
  682.         Clip3d(&n, eyec, ceyec);
  683.         if (n < 3)
  684.             return;
  685.         Project(n, ceyec, cndc);
  686.         if (the3dPort->cullbacks) {
  687.             ax = cndc[1].x - cndc[0].x;
  688.             ay = cndc[1].y - cndc[0].y;
  689.             bx = cndc[2].x - cndc[1].x;
  690.             by = cndc[2].y - cndc[1].y;
  691.             if (ax * by - ay * bx > 0.0)
  692.                 return;
  693.         }
  694.         ndc2fdc(n, cndc, cfdc);
  695.         
  696.         GetForeColor(&saveColor);
  697.         GetBackColor(&eraseColor);
  698.         RGBForeColor(&eraseColor);
  699.     
  700.         if (the3dPort->onlyqd) {
  701.             PolyForm(n, cfdc);
  702.             PaintPoly(&polyptr);
  703.         } else {
  704.             for (i = 0; i < n; i++) {
  705.                 rgb2cv(&eraseColor, &cfrgb[i]);
  706.             }
  707.             GouraudShade(n, cfdc, cfrgb);
  708.         }
  709.         RGBForeColor(&saveColor);
  710.     }
  711. }
  712.  
  713. void
  714. PolyC3dFill(int n, vector x[], vector c[])
  715. /*
  716.     Fill the polygon defined by the n vertices in x.  The 
  717.     resulting polygon will be color filled with a bilinear
  718.     interpolation based on the vertex colors in c.
  719. */
  720. {
  721.     int        i;
  722.     FixedVector    avgcolor = {0, 0, 0};
  723.     FixedVector    t;
  724.     RGBColor    saveColor, rgb;
  725.     double        ax, ay, bx, by;    
  726.     
  727.     if (the3dPort->wireframe) {
  728.         PolyC3dFrame(n, x, c);
  729.     } else {
  730.         if (n < 3)
  731.             return;
  732.         Transform(n, x, eyec);
  733.         ClipC3d(&n, eyec, ceyec, c, ccolor);
  734.         if (n < 3)
  735.             return;
  736.         Project(n, ceyec, cndc);
  737.         if (the3dPort->cullbacks) {
  738.             ax = cndc[1].x - cndc[0].x;
  739.             ay = cndc[1].y - cndc[0].y;
  740.             bx = cndc[2].x - cndc[1].x;
  741.             by = cndc[2].y - cndc[1].y;
  742.             if (ax * by - ay * bx > 0.0)
  743.                 return;
  744.         }
  745.         ndc2fdc(n, cndc, cfdc);
  746.         
  747.         LoadFColors(n, ccolor);
  748.     
  749.         GetForeColor(&saveColor);
  750.         if (the3dPort->onlyqd) {
  751.             double    t2 = 1.0/n;
  752.             Fixed    s;
  753.             extended    ext;
  754.             
  755. #if    __option(mc68881)
  756.             x96tox80(&t2, &ext);
  757.             s = X2Fix(ext);
  758. #else
  759.             x96tox80(&t2, &ext);
  760.             s = X2Fix(ext);
  761. #endif
  762.             for (i = 0; i < n; i++) {
  763.                 fvscale(s, &cfrgb[i], &t);
  764.                 fvadd(&t, &avgcolor, &avgcolor);
  765.             }
  766.             cv2rgb(&avgcolor, &rgb);
  767.             RGBForeColor(&rgb);
  768.             PolyForm(n, cfdc);
  769.             PaintPoly(&polyptr);
  770.         } else {
  771.             GouraudShade(n, cfdc, cfrgb);
  772.         }
  773.         RGBForeColor(&saveColor);
  774.     }
  775. }
  776.  
  777. /*    ============================================================    */
  778. /*    Some default marking functions:                                    */
  779.  
  780. void
  781. MarkPoint(vector *pos)
  782. /*
  783.     This marks the world coordinate pos with a single pixel of the
  784.     current foreground color.
  785.     
  786.     If the point is outside the view volume, the point is not marked.
  787. */
  788. {
  789.     FixedVector        x;
  790.     IntVector        ix;
  791.     RGBColor        color;
  792.     int                i = 1;
  793.     
  794.     TranClipProjf(&i, pos, &x);
  795.     if (!i)
  796.         return;
  797.     
  798.     fv2iv(&x, &ix);
  799.     
  800.     GetForeColor(&color);
  801.     SetCPixel(ix.x, ix.y, &color);
  802. }
  803.  
  804. void
  805. MarkSelectedPoint(vector *pos)
  806. /*
  807.     This marks the world coordinate pos with an "x" of the
  808.     current foreground color.
  809.     
  810.     The size of the mark is twice that defined by SLTNWDTH.
  811.     
  812.     If the point is outside the view volume, the point is not marked.
  813. */
  814. {
  815.     FixedVector        x;
  816.     IntVector        ix;
  817.     int                i = 1;
  818.     
  819.     TranClipProjf(&i, pos, &x);
  820.     if (!i)
  821.         return;
  822.  
  823.     fv2iv(&x, &ix);
  824.  
  825.     MoveTo(ix.x - SLTNWDTH, ix.y);
  826.     LineTo(ix.x + SLTNWDTH, ix.y);
  827.     MoveTo(ix.x, ix.y - SLTNWDTH);
  828.     LineTo(ix.x, ix.y + SLTNWDTH);
  829. }
  830.  
  831. void
  832. MarkCtrlPoint(vector *pos)
  833. /*
  834.     This marks the world coordinate pos with a square of the
  835.     current foreground color.
  836.     
  837.     The size of the mark is twice that defined by CNTRLWDTH.
  838.     
  839.     If the point is outside the view volume, the point is not marked.
  840. */
  841. {
  842.     Rect    r;
  843.     FixedVector        x;
  844.     IntVector        ix;
  845.     int                i = 1;
  846.     
  847.     TranClipProjf(&i, pos, &x);
  848.     if (!i)
  849.         return;
  850.  
  851.     fv2iv(&x, &ix);
  852.  
  853.     r.left = r.right = ix.x;
  854.     r.top = r.bottom = ix.y;
  855.     r.top -= CNTRLWDTH;
  856.     r.left -= CNTRLWDTH;
  857.     r.right += CNTRLWDTH;
  858.     r.bottom += CNTRLWDTH;
  859.     
  860.     PaintRect(&r);
  861. }
  862.